//
// Created by Administrator on 2023/5/28.
//

#ifndef WIDGET_EVENT_H
#define WIDGET_EVENT_H
#define RANGE 5


#include <QMouseEvent>
#include <QCursor>


template <typename Owner>
class Widget_Event
{
public:
    Widget_Event(Owner* owner);


    ~Widget_Event();


    void mouseMoveEvent(QMouseEvent* event);
    void mousePressEvent(QMouseEvent* event);
    void mouseReleaseEvent(QMouseEvent* event);


    int Region(QPoint pos);
    void Set_Cursor(int xy);



private:
    Widget_Event(void);

    Owner* owner;


    QRect owner_geometry;


    QPoint press_pos;
    QPoint move_pos;
    int range;
    bool size_press;
    bool move_press;

};


template <typename Owner>
Widget_Event<Owner>::Widget_Event(Owner* owner): owner(owner){}


template <typename Owner>
Widget_Event<Owner>::~Widget_Event(){}


template <typename Owner>
Widget_Event<Owner>::Widget_Event(void){}


template <typename Owner>
void Widget_Event<Owner>::mouseMoveEvent(QMouseEvent* event)
{
    this->Set_Cursor(this->Region(event->pos()));
    QPoint temp_pos = event->globalPos();
    QPoint move_size = temp_pos - this->press_pos;
    QRect temp_geometry = this->owner_geometry;


    if (this->size_press)
    {
        switch (this->range)
        {
            case 11:
                temp_geometry.setTopLeft(temp_geometry.topLeft() + move_size);
                break;
            case 12:
                temp_geometry.setTop(temp_geometry.top() + move_size.y());
                break;
            case 13:
                temp_geometry.setTopRight(temp_geometry.topRight() + move_size);
                break;
            case 21:
                temp_geometry.setLeft(temp_geometry.left() + move_size.x());
                break;
            case 23:
                temp_geometry.setRight(temp_geometry.right() + move_size.x());
                break;
            case 31:
                temp_geometry.setBottomLeft(temp_geometry.bottomLeft() + move_size);
                break;
            case 32:
                temp_geometry.setBottom(temp_geometry.bottom() + move_size.y());
                break;
            case 33:
                temp_geometry.setBottomRight(temp_geometry.bottomRight() + move_size);
                break;
            default:
                break;
        }

        if (((temp_geometry.width() <= 1920) && (temp_geometry.height() <= 1080)) && ((temp_geometry.width() >= this->owner->minimumWidth()) && (temp_geometry.height() >= this->owner->minimumHeight())))
        {
            this->owner->setGeometry(temp_geometry);
        }
    }
    else if (this->move_press)
    {

        QPoint temp_pos = event->globalPos();
        QPoint mouse_end = temp_pos - this->move_pos;
        this->owner->move(mouse_end);
    }

}
template <typename Owner>
void Widget_Event<Owner>::mousePressEvent(QMouseEvent* event)
{
    if(event->button() == Qt::LeftButton)
    {
        this->range = this->Region(event->pos());

        this->size_press = (this->range != 22) ? (true) : (false);
        this->move_press = (this->range == 22) ? (true) : (false);
        this->press_pos = event->globalPos();
        this->move_pos = event->pos();

        this->owner_geometry = this->owner->geometry();
    }
}
template <typename Owner>
void Widget_Event<Owner>::mouseReleaseEvent(QMouseEvent* event)
{
    this->size_press = false;
    this->move_press = false;
}


template <typename Owner>
int Widget_Event<Owner>::Region(QPoint pos)
{
    int p_x = pos.x();
    int p_y = pos.y();

    int w{this->owner->geometry().width()};
    int h{this->owner->geometry().height()};


    int y{(p_y < RANGE) ? (10) : ((p_y > h - RANGE) ? (30) : (20))};
    int x{(p_x < RANGE) ? (1) : ((p_x > w - RANGE) ? (3) : (2))};

    int xy {x + y};

    return xy;
}


template <typename Owner>
void Widget_Event<Owner>::Set_Cursor(int xy)
{
    QCursor cur;
    switch(xy)
    {
        case 11:
            cur = Qt::SizeFDiagCursor;
            break;
        case 12:
            cur = Qt::SizeVerCursor;
            break;
        case 13:
            cur = Qt::SizeBDiagCursor;
            break;
        case 21:
            cur = Qt::SizeHorCursor;
            break;
        case 22:
            break;
        case 23:
            cur = Qt::SizeHorCursor;
            break;
        case 31:
            cur = Qt::SizeBDiagCursor;
            break;
        case 32:
            cur = Qt::SizeVerCursor;
            break;
        case 33:
            cur = Qt::SizeFDiagCursor;
            break;
        default:
            cur = Qt::ArrowCursor;
            break;
    }
    this->owner->setCursor(cur);
}





#endif //BASE_WIDGET_WIDGET_EVENT_H
